// @Author miaoqing
// @Date 2024/02/29 17:33:00
// @Desc
package logic

import (
	"core/command"
	"core/common"
	"core/component/function"
	"core/component/logger"
	gonsq "core/component/nsq"
	"github.com/golang/protobuf/proto"
	"github.com/nsqio/go-nsq"
	"runtime/debug"
)

type MsgHandler func(cmd command.NsqCmd, data []byte)

type CommonNsqMessageHandler struct {
	handlers map[command.NsqCmd]MsgHandler
}

func (cnm *CommonNsqMessageHandler) HandleMessage(msg *nsq.Message) error {
	defer func() {
		if err := recover(); err != nil {
			// 发送报警短信
			stackMsg := string(debug.Stack())
			function.WritePanic(stackMsg, err)
			logger.Errorf("[异常] player goroutine出错 err:%v stack:\n%v", err, stackMsg)
			return
		}
	}()
	requset := command.ComplexMessage{}
	err := proto.Unmarshal(msg.Body, &requset)
	if err != nil {
		logger.Error("[NSQ] 消息错误:", err)
		return nil
	}
	if requset.SendTime < ServerInstance().startTime {
		return nil
	}
	handler, ok := cnm.handlers[requset.Nsqcmd]
	if ok {
		handler(requset.Nsqcmd, requset.Data)
		logger.Infof("[NSQ] 已处理NSQ消息 消息ID:%v", requset.Nsqcmd)
	} else {
		logger.Errorf("[NSQ] 未知的消息 cmd:%v", requset.Nsqcmd)
		return nil
	}
	return nil
}

func (cnm *CommonNsqMessageHandler) registerHandler() {}

var (
	commonConsumer *nsq.Consumer
	commonHandler  *CommonNsqMessageHandler
)

func nsqProcessMgrInit() {
	gonsq.CreateTopic(gonsq.LogicNSQ, common.Online_Topic)
	commonHandler = &CommonNsqMessageHandler{
		handlers: make(map[command.NsqCmd]MsgHandler),
	}
	commonHandler.registerHandler()
	channel := ServerInstance().getNSQChannel()
	commonConsumer = gonsq.NewConsumer(gonsq.LogicNSQ, common.Online_Topic, channel, commonHandler)
	//crossSrvChatGetMe().initNsqHandler(serverInstance().getZoneNSQChannel())
	//privateChatGetMe().initNsqHandler(channel)
	//systemMsgGetMe().initNsqHandler(channel)
}

func nsqProcessMgrEnd() {
	channel := ServerInstance().getNSQChannel()
	//gonsq.DeleteChannel(gonsq.ChatNSQ, common.CHAT_TOPIC, serverInstance().getZoneNSQChannel())
	//gonsq.DeleteChannel(gonsq.ChatNSQ, common.PRIVATECHAT_TOPIC, channel)
	gonsq.DeleteChannel(gonsq.LogicNSQ, common.Online_Topic, channel)
	//gonsq.DeleteChannel(gonsq.LogicNSQ, common.SYSMSG, channel)
	//crossSrvChatGetMe().stop()
	//privateChatGetMe().stop()
	commonConsumer.Stop()
	//systemMsgGetMe().stop()
}
